import * as THREE from 'three'
import { useEffect } from 'react'

/**
 * 设置渲染器宽高
 * 通过监听onresize事件实现自适应
 */

function APP() {
  useEffect(() => {
    /** 创建场景 */
    const scene = new THREE.Scene();
    // 创建一个立方缓冲几何体
    const geometry = new THREE.BoxGeometry(100, 100, 100);
    // 创建材质
    const material = new THREE.MeshLambertMaterial({ color: 0xffffff });
    // 生成带有材质的物体
    const cube = new THREE.Mesh(geometry, material);
    // 将物体添加到场景中
    scene.add(cube);
    // 创建光源
    // 环境光，没有特定的方向
    const ambientLight = new THREE.AmbientLight(0x444444);
    scene.add(ambientLight);
    // 平行光，类似于太阳光
    const directionalLight = new THREE.DirectionalLight(0xabcdef, 1);
    directionalLight.position.set(400, 200, 300);
    scene.add(directionalLight);

    /** 相机 */
    // 相机设置
    const width = window.innerWidth; // 窗口宽度
    const height = window.innerHeight; // 窗口高度
    let k = width / height; // 窗口宽高比
    const s = 200; // 三维场景控制系数，系数越大，场景显示越大
    // 创建相机对象
    // const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, -1, 1000); // 正交相机
    const camera = new THREE.PerspectiveCamera(45, k, 1, 1000); // 透视相机
    camera.position.set(200, 200, 200); // 设置相机位置
    camera.up.set(0, 1, 0); // 设置相机角度
    camera.lookAt(scene.position); // 设置相机方向(指向场景对象)

    /** 创建渲染器对象 */
    const renderer = new THREE.WebGLRenderer();

    // 监听onresize事件，当可视窗口发生变化时自动同步渲染区域尺寸
    // 正交相机
    // window.onresize = () => {
    //   // 重置渲染器输入画布尺寸
    //   renderer.setSize(window.innerWidth, window.innerHeight); 
    //   // 重置相机投影的相关参数
    //   k = window.innerWidth / window.innerHeight; // 窗口宽高比
    //   camera.left = -s * k;
    //   camera.right = s * k;
    //   camera.top = s;
    //   camera.bottom = -s;
    //   // 渲染器执行render方法的时候回读取相机对象的投影矩阵属性projectionMatrix
    //   // 但是不会每渲染一帧，就通过相机的属性计算投影矩阵（节约计算资源）
    //   // 如果相机的一些属性发生了变化，需要执行updateProjectionMatrix()方法更新相机的投影矩阵
    //   camera.updateProjectionMatrix();
    // }
    
    // 透视相机
    window.onresize = () => {
      // 重置渲染器输入画布尺寸
      renderer.setSize(window.innerWidth, window.innerHeight);
      // 全屏情况下：设置观察范围长宽比aspect为窗口宽高比
      camera.aspect = window.innerWidth / innerHeight;
      // 渲染器执行render方法的时候回读取相机对象的投影矩阵属性projectionMatrix
      // 但是不会每渲染一帧，就通过相机的属性计算投影矩阵（节约计算资源）
      // 如果相机的一些属性发生了变化，需要执行updateProjectionMatrix()方法更新相机
      camera.updateProjectionMatrix();
    }
    document.body.appendChild(renderer.domElement); // body元素中插入canvas对象

    renderer.render(scene, camera); // 执行渲染操作
  }, [])
  return (
    <div className='APP'></div>
  )
}

export default APP